package top.blackr.folivora.common.pay.refund;


import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import com.wechat.pay.java.service.refund.model.Status;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.blackr.folivora.common.pay.exception.RefundException;
import top.blackr.folivora.common.pay.refund.entity.RefundInformation;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 购物退款接口
 */
@Slf4j
@Service(RefundStrategyConstant.DEFAULT_WX_REFUND_SERVER_NAME)
public class DefaultWxRefundStrategy<I extends RefundInformation> implements RefundStrategy<I> {

    @Autowired
    private NotificationConfig notificationConfig;

    @Override
    public void noticeCallback(HttpServletRequest request, Consumer<String> consumer) throws IOException {
        StringBuilder sb = new StringBuilder();
        try {
            BufferedReader br = request.getReader();
            String str;
            while ((str = br.readLine()) != null) {
                sb.append(str);
            }
            // 构造 RequestParam
            RequestParam requestParam = new RequestParam.Builder()
                    .serialNumber(request.getHeader("Wechatpay-Serial"))
                    .nonce(request.getHeader("Wechatpay-Nonce"))
                    .signature(request.getHeader("Wechatpay-Signature"))
                    .timestamp(request.getHeader("Wechatpay-Timestamp"))
                    .body(String.valueOf(sb))
                    .build();

            if (requestParam.getSignature().contains("WECHATPAY/SIGNTEST")) {
                throw new RefundException("微信回调探测流量");
            }

            // 初始化 NotificationParser
            NotificationParser parser = new NotificationParser(notificationConfig);
            // 以支付通知回调为例，验签、解密并转换成 Transaction
            RefundNotification transaction = parser.parse(requestParam, RefundNotification.class);

            if (Status.SUCCESS.equals(transaction.getRefundStatus())) {
                // 退款单号，内部系统的
                String outRefundNo = transaction.getOutRefundNo();
                consumer.accept(outRefundNo);
            }
        } catch (RefundException refundException) {
            throw refundException;
        } catch (Exception e) {
            // 获取所有的header名称
            Enumeration<String> headerNames = request.getHeaderNames();
            Map<String, String> headers = new HashMap<>();
            // 遍历并打印每个header的名称和值
            if (headerNames != null) {
                while (headerNames.hasMoreElements()) {
                    String headerName = headerNames.nextElement();
                    String headerValue = request.getHeader(headerName);
                    headers.put(headerName, headerValue);
                }
            }
            log.error("微信退款回调逻辑异常-body:{}\nheaders:{}", JsonUtil.toJson(sb.toString()), JsonUtil.toJson(headers), e);
            throw e;
        }
    }

}
